﻿using System.Globalization;

namespace Akabana.Amf.Messaging
{
    public static class StringExt
    {
        public static byte[] toUIDBytes(this string str)
        {
            byte[] result = null;
            if (isUID(str))
            {
                result = new byte[18];
                var resultIndex = 0;

                for (int i = 0; i < str.Length; i++)
                {
                    char c = str[i];
                    if (c == '-')
                    {
                        continue;
                    }
                    int h1 = getDigit(c);
                    i++;
                    int h2 = getDigit(str[i]);

                    int value = ((h1 << 4) | h2) & 0xFF;
                    result[resultIndex++] = (byte)value;
                }
            }
            return result;
        }

        public static bool isUID(this string uid)
        {
            if (uid != null && uid.Length == 36)
            {
                for (int i = 0; i < 36; i++)
                {
                    char c = uid[i];

                    // Check for correctly placed hyphens
                    if (i == 8 || i == 13 || i == 18 || i == 23)
                    {
                        if (c != 45)
                        {
                            return false;
                        }
                    }
                    // We allow capital alpha-numeric hex digits only
                    else if (c < 48 || c > 70 || (c > 57 && c < 65))
                    {
                        return false;
                    }
                }

                return true;
            }

            return false;
        }

        private static int getDigit(char hex)
        {
            switch (hex) 
            {
                case 'A': 
                case 'a':           
                    return 10;
                case 'B':
                case 'b':
                    return 11;
                case 'C':
                case 'c':
                    return 12;
                case 'D':
                case 'd':
                    return 13;
                case 'E':
                case 'e':
                    return 14;                
                case 'F':
                case 'f':
                    return 15;

                case '0':
                    return 0;
                case '1':
                    return 1;
                case '2':
                    return 2;
                case '3':
                    return 3;
                case '4':
                    return 4;
                case '5':
                    return 5;
                case '6':
                    return 6;
                case '7':
                    return 7;
                case '8':
                    return 8;
                case '9':
                    return 9;

                default:
                    return 0;
            }    
        }
    }
}
